package org.eiahe.hr.interview.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.eiahe.hr.interview.domain.InterviewQuestionBank;
import org.eiahe.hr.interview.domain.dto.InterviewQuestionBankDTO;
import org.eiahe.hr.interview.domain.vo.InterviewQuestionBankVo;
import org.eiahe.hr.interview.service.InterviewQuestionBankService;
import org.eiahe.hr.interview.domain.dto.InterviewQuestionBankQueryDTO;
import org.eiahe.hr.interview.mapper.InterviewQuestionBankMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author :zhangnn
 * @className :InterviewQuestionBankServiceImpl
 * @description: TODO
 * @date 2025-08-19 14:13:43
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InterviewQuestionBankServiceImpl extends ServiceImpl<InterviewQuestionBankMapper, InterviewQuestionBank> implements InterviewQuestionBankService {
    private final InterviewQuestionBankMapper questionBankMapper;

    /**
     * 分页查询题库列表
     */
    @Override
    public TableDataInfo<InterviewQuestionBankVo> selectQuestionBankPage(InterviewQuestionBankQueryDTO queryDTO, PageQuery pageQuery) {
        LambdaQueryWrapper<InterviewQuestionBank> wrapper = buildQueryWrapper(queryDTO);

        IPage<InterviewQuestionBankVo> page = questionBankMapper.selectVoPage(pageQuery.build(), wrapper);

        return TableDataInfo.build(page);
    }


    /**
     * 查询所有可用的题库（未删除的）
     */
    @Override
    public List<InterviewQuestionBankDTO> selectAllEnabled() {
        LambdaQueryWrapper<InterviewQuestionBank> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(InterviewQuestionBank::getDelFlag, 0)
            .orderByAsc(InterviewQuestionBank::getParentId)
            .orderByDesc(InterviewQuestionBank::getCreateTime);

        List<InterviewQuestionBank> list = questionBankMapper.selectList(wrapper);
        return list.stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
    }

    /**
     * 根据ID查询题库详情
     */
    @Override
    public InterviewQuestionBankDTO selectById(Long id) {
        InterviewQuestionBank entity = questionBankMapper.selectById(id);
        if (entity == null || entity.getDelFlag().equals("1")) {
            return null;
        }
        return convertToDTO(entity);
    }

    /**
     * 新增题库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertQuestionBank(InterviewQuestionBankDTO bankDTO) {
        // 校验题库名称唯一性
        if (checkBankNameExists(bankDTO.getBankName())) {
            throw new RuntimeException("题库名称已存在");
        }

        InterviewQuestionBank entity = convertToEntity(bankDTO);

        if (entity.getParentId() == null) {
            entity.setParentId(0L);
        }

        int result = questionBankMapper.insert(entity);
        return result > 0;
    }

    /**
     * 更新题库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuestionBank(InterviewQuestionBankDTO bankDTO) {
        if (bankDTO.getId() == null) {
            throw new RuntimeException("题库ID不能为空");
        }

        // 校验题库名称唯一性（排除当前记录）
        if (checkBankNameExistsExclude(bankDTO.getBankName(), bankDTO.getId())) {
            throw new RuntimeException("题库名称已存在");
        }

        InterviewQuestionBank entity = convertToEntity(bankDTO);
        int result = questionBankMapper.updateById(entity);
        return result > 0;
    }

    /**
     * 删除题库（逻辑删除）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteQuestionBank(Long id) {
        if (id == null) {
            return false;
        }

        // 检查是否有子题库
        long childCount = count(new LambdaQueryWrapper<InterviewQuestionBank>()
            .eq(InterviewQuestionBank::getParentId, id)
            .eq(InterviewQuestionBank::getDelFlag, 0));

        if (childCount > 0) {
            throw new RuntimeException("存在子题库，无法删除");
        }

        LambdaUpdateWrapper<InterviewQuestionBank> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(InterviewQuestionBank::getId, id)
            .set(InterviewQuestionBank::getDelFlag, 1)
            .set(InterviewQuestionBank::getUpdateTime, LocalDateTime.now());

        int result = questionBankMapper.update(null, wrapper);
        return result > 0;
    }

    /**
     * 批量删除题库（逻辑删除）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteQuestionBankByIds(List<Long> ids) {
        if (ObjectUtil.isEmpty(ids)) {
            return false;
        }

        // 检查每个要删除的题库是否有子题库
        for (Long id : ids) {
            long childCount = count(new LambdaQueryWrapper<InterviewQuestionBank>()
                .eq(InterviewQuestionBank::getParentId, id)
                .eq(InterviewQuestionBank::getDelFlag, 0));

            if (childCount > 0) {
                throw new RuntimeException("存在子题库，无法删除");
            }
        }

        LambdaUpdateWrapper<InterviewQuestionBank> wrapper = Wrappers.lambdaUpdate();
        wrapper.in(InterviewQuestionBank::getId, ids)
            .set(InterviewQuestionBank::getDelFlag, 1)
            .set(InterviewQuestionBank::getUpdateTime, LocalDateTime.now());

        int result = questionBankMapper.update(null, wrapper);
        return result > 0;
    }

    /**
     * 检查题库名称是否存在
     */
    @Override
    public boolean checkBankNameExists(String bankName) {
        if (StringUtils.isBlank(bankName)) {
            return false;
        }
        long count = count(new LambdaQueryWrapper<InterviewQuestionBank>()
            .eq(InterviewQuestionBank::getBankName, bankName)
            .eq(InterviewQuestionBank::getDelFlag, 0));

        return count > 0;
    }

    /**
     * 检查题库名称是否存在（排除指定ID）
     */
    @Override
    public boolean checkBankNameExistsExclude(String bankName, Long excludeId) {
        if (StringUtils.isBlank(bankName) || excludeId == null) {
            return false;
        }

        long count = count(new LambdaQueryWrapper<InterviewQuestionBank>()
            .eq(InterviewQuestionBank::getBankName, bankName)
            .eq(InterviewQuestionBank::getDelFlag, 0)
            .ne(InterviewQuestionBank::getId, excludeId));

        return count > 0;
    }

    /**
     * 根据父级ID查询子题库列表
     */
    @Override
    public List<InterviewQuestionBankDTO> selectByParentId(Long parentId) {
        LambdaQueryWrapper<InterviewQuestionBank> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(InterviewQuestionBank::getParentId, parentId == null ? 0L : parentId)
            .eq(InterviewQuestionBank::getDelFlag, 0)
            .orderByDesc(InterviewQuestionBank::getCreateTime);

        List<InterviewQuestionBank> list = questionBankMapper.selectList(wrapper);
        return list.stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<InterviewQuestionBank> buildQueryWrapper(InterviewQuestionBankQueryDTO queryDTO) {
        LambdaQueryWrapper<InterviewQuestionBank> wrapper = Wrappers.lambdaQuery();

        // 默认查询未删除的数据
        wrapper.eq(InterviewQuestionBank::getDelFlag, 0);

        if (queryDTO != null) {
            // 题库名称模糊查询
            if (StringUtils.isNotBlank(queryDTO.getBankName())) {
                wrapper.like(InterviewQuestionBank::getBankName, queryDTO.getBankName());
            }

            // 父级ID查询
            if (queryDTO.getParentId() != null) {
                wrapper.eq(InterviewQuestionBank::getParentId, queryDTO.getParentId());
            }

            // 创建时间范围查询
            if (queryDTO.getBeginTime() != null) {
                wrapper.ge(InterviewQuestionBank::getCreateTime, queryDTO.getBeginTime());
            }
            if (queryDTO.getEndTime() != null) {
                wrapper.le(InterviewQuestionBank::getCreateTime, queryDTO.getEndTime());
            }
        }

        // 默认按创建时间倒序
        wrapper.orderByAsc(InterviewQuestionBank::getCreateTime);

        return wrapper;
    }

    /**
     * 实体转VO
     */
    private InterviewQuestionBankVo convertToVO(InterviewQuestionBank entity) {
        if (entity == null) {
            return null;
        }

        InterviewQuestionBankVo vo = new InterviewQuestionBankVo();
        BeanUtil.copyProperties(entity, vo);

        // 设置父级题库名称
        if (entity.getParentId() != null && entity.getParentId() > 0) {
            InterviewQuestionBank parent = questionBankMapper.selectById(entity.getParentId());
            if (parent != null) {
                vo.setParentBankName(parent.getBankName());
            }
        }

        return vo;
    }

    /**
     * 实体转DTO
     */
    private InterviewQuestionBankDTO convertToDTO(InterviewQuestionBank entity) {
        if (entity == null) {
            return null;
        }

        InterviewQuestionBankDTO dto = new InterviewQuestionBankDTO();
        BeanUtil.copyProperties(entity, dto);
        return dto;
    }

    /**
     * DTO转实体
     */
    private InterviewQuestionBank convertToEntity(InterviewQuestionBankDTO dto) {
        if (dto == null) {
            return null;
        }

        InterviewQuestionBank entity = new InterviewQuestionBank();
        BeanUtil.copyProperties(dto, entity);
        return entity;
    }
}
